<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'

interface Props {
  title?: string
  showConfirm?: boolean
  showCancel?: boolean
  confirmText?: string
  cancelText?: string
  maskClosable?: boolean
  width?: string | number
  height?: string | number
  maxWidth?: string | number
  maxHeight?: string | number
  minWidth?: string | number
  minHeight?: string | number
}

interface Emits {
  (e: 'close'): void
  (e: 'confirm'): void
  (e: 'cancel'): void
}

const props = withDefaults(defineProps<Props>(), {
  title: '',
  showConfirm: true,
  showCancel: true,
  confirmText: '确认',
  cancelText: '取消',
  maskClosable: true,
  width: 'auto',
  height: 'auto',
  maxWidth: '90vw',
  maxHeight: '90vh',
  minWidth: '400px',
  minHeight: 'auto',
})

const emit = defineEmits<Emits>()

const visible = ref(false)

onMounted(() => {
  visible.value = true
  document.body.style.overflow = 'hidden'
})

onUnmounted(() => {
  document.body.style.overflow = ''
})

function handleMaskClick() {
  if (props.maskClosable) {
    handleClose()
  }
}

function handleClose() {
  visible.value = false
  setTimeout(() => {
    emit('close')
  }, 300)
}

function handleConfirm() {
  emit('confirm')
}

function handleCancel() {
  emit('cancel')
}

function handleContentClick(event: Event) {
  event.stopPropagation()
}

function formatSize(size: string | number): string {
  return typeof size === 'number' ? `${size}px` : size
}
</script>

<template>
  <Teleport to="body">
    <transition name="pop-panel">
      <div v-if="visible" class="pop-panel-overlay" @click="handleMaskClick">
        <div
          class="pop-panel-content"
          :style="{
            width: formatSize(width),
            height: formatSize(height),
            maxWidth: formatSize(maxWidth),
            maxHeight: formatSize(maxHeight),
            minWidth: formatSize(minWidth),
            minHeight: formatSize(minHeight),
          }"
          @click="handleContentClick"
        >
          <div v-if="title || $slots.header" class="pop-panel-header">
            <slot name="header">
              <h3 class="pop-panel-title">
                {{ title }}
              </h3>
            </slot>
            <button class="pop-panel-close" @click="handleClose">
              ×
            </button>
          </div>

          <div class="pop-panel-body">
            <slot />
          </div>

          <div v-if="(showConfirm || showCancel) || $slots.footer" class="pop-panel-footer">
            <slot name="footer">
              <button v-if="showCancel" class="pop-panel-btn pop-panel-btn--cancel" @click="handleCancel">
                {{ cancelText }}
              </button>
              <button v-if="showConfirm" class="pop-panel-btn pop-panel-btn--confirm" @click="handleConfirm">
                {{ confirmText }}
              </button>
            </slot>
          </div>
        </div>
      </div>
    </transition>
  </Teleport>
</template>

<style scoped>
.pop-panel-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.pop-panel-content {
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
}

.pop-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px 0;
  margin-bottom: 8px;
}

.pop-panel-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.pop-panel-close {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #999;
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pop-panel-close:hover {
  color: #666;
}

.pop-panel-body {
  padding: 24px;
  flex: 1;
  overflow-y: auto;
}

.pop-panel-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 0 24px 24px;
  margin-top: 8px;
}

.pop-panel-btn {
  padding: 8px 16px;
  border-radius: 4px;
  border: 1px solid;
  cursor: pointer;
  font-size: 14px;
  min-width: 80px;
}

.pop-panel-btn--cancel {
  background: white;
  border-color: #d9d9d9;
  color: #666;
}

.pop-panel-btn--cancel:hover {
  border-color: #40a9ff;
  color: #40a9ff;
}

.pop-panel-btn--confirm {
  color: white;
}

.pop-panel-enter-active,
.pop-panel-leave-active {
  transition: opacity 0.3s ease;
}

.pop-panel-enter-from,
.pop-panel-leave-to {
  opacity: 0;
}

.pop-panel-content {
  transition: transform 0.3s ease;
}

.pop-panel-enter-from .pop-panel-content,
.pop-panel-leave-to .pop-panel-content {
  transform: scale(0.9);
}
</style>
